var Geo;
(function (Geo) {
    (function (CoordinateConverter) {
        var CoordinateConverterViewModel = (function () {
            function CoordinateConverterViewModel(coordinateConverter, coordinateInputElement, gpsOutputElement, dmsOutputElement, decimalOutputElement, onInputChanged) {
                this._coordinateConverter = coordinateConverter;
                this._coordinateInputElement = coordinateInputElement;
                this._gpsOutputElement = gpsOutputElement;
                this._dmsOutputElement = dmsOutputElement;
                this._decimalOutputElement = decimalOutputElement;
                this._coordinateInputElement.onkeyup = onInputChanged;
            }
            CoordinateConverterViewModel.prototype.GetPosition = function () {
                var _this = this;
                navigator.geolocation.getCurrentPosition(function (position) {
                    _this.GotPosition(new Geo.CoordinateConverter.Model.CoordinateDecimalInfo(position.coords.latitude, position.coords.longitude));
                    var maxAge = new Date(Date.now() - 20000);
                    if(position.coords.accuracy > 50 || position.timestamp < maxAge) {
                        _this.GetPositionL2();
                    }
                }, function (err) {
                    alert('GetPosition navigator.geolocation.getCurrentPosition ERROR ' + err.message);
                }, {
                    maximumAge: Infinity
                });
            };
            CoordinateConverterViewModel.prototype.GetPositionL2 = function () {
                var _this = this;
                navigator.geolocation.getCurrentPosition(function (position) {
                    _this.GotPosition(new Geo.CoordinateConverter.Model.CoordinateDecimalInfo(position.coords.latitude, position.coords.longitude));
                    var maxAge = new Date(Date.now() - 10000);
                    if(position.coords.accuracy > 20 || position.timestamp < maxAge) {
                        _this.GetPositionL3();
                    }
                }, function (err) {
                    alert('GetPositionL2 navigator.geolocation.getCurrentPosition ERROR ' + err.message);
                }, {
                    maximumAge: 30000
                });
            };
            CoordinateConverterViewModel.prototype.GetPositionL3 = function () {
                var _this = this;
                navigator.geolocation.getCurrentPosition(function (position) {
                    _this.GotPosition(new Geo.CoordinateConverter.Model.CoordinateDecimalInfo(position.coords.latitude, position.coords.longitude));
                }, function (err) {
                    alert('GetPositionL3 navigator.geolocation.getCurrentPosition ERROR ' + err.message);
                }, {
                    enableHighAccuracy: true
                });
            };
            CoordinateConverterViewModel.prototype.GotPosition = function (position) {
                var newPosition = position.ToString();
                if(this.CoordinateInput != newPosition) {
                    this.CoordinateInput = newPosition;
                    this.InputChanged();
                }
            };
            CoordinateConverterViewModel.prototype.InputChanged = function () {
                try  {
                    this.Model = this.CoordinateConverter.ParseCoordinateDms(this.CoordinateInput);
                    this.CoordinateDecimalOutput = this.Model.ToCoordinateDecimal().ToString();
                    this.CoordinateGpsOutput = this.Model.ToCoordinateDm().ToString();
                    this.CoordinateDmsOutput = this.Model.ToCoordinateDms().ToString();
                    initialize();
                } catch (ex) {
                    this.Model = null;
                    this.CoordinateDecimalOutput = '';
                    this.CoordinateGpsOutput = '';
                    this.CoordinateDmsOutput = '';
                }
            };
            Object.defineProperty(CoordinateConverterViewModel.prototype, "CoordinateConverter", {
                get: function () {
                    return this._coordinateConverter;
                },
                enumerable: true,
                configurable: true
            });
            Object.defineProperty(CoordinateConverterViewModel.prototype, "Model", {
                get: function () {
                    return this._model;
                },
                set: function (value) {
                    this._model = value;
                },
                enumerable: true,
                configurable: true
            });
            Object.defineProperty(CoordinateConverterViewModel.prototype, "CoordinateInput", {
                get: function () {
                    return this._coordinateInputElement.value;
                },
                set: function (value) {
                    this._coordinateInputElement.value = value;
                },
                enumerable: true,
                configurable: true
            });
            Object.defineProperty(CoordinateConverterViewModel.prototype, "CoordinateDecimalOutput", {
                set: function (value) {
                    this._decimalOutputElement.innerHTML = value;
                },
                enumerable: true,
                configurable: true
            });
            Object.defineProperty(CoordinateConverterViewModel.prototype, "CoordinateGpsOutput", {
                set: function (value) {
                    this._gpsOutputElement.innerHTML = value;
                },
                enumerable: true,
                configurable: true
            });
            Object.defineProperty(CoordinateConverterViewModel.prototype, "CoordinateDmsOutput", {
                set: function (value) {
                    this._dmsOutputElement.innerHTML = value;
                },
                enumerable: true,
                configurable: true
            });
            return CoordinateConverterViewModel;
        })();
        CoordinateConverter.CoordinateConverterViewModel = CoordinateConverterViewModel;        
    })(Geo.CoordinateConverter || (Geo.CoordinateConverter = {}));
    var CoordinateConverter = Geo.CoordinateConverter;
})(Geo || (Geo = {}));
var ViewModel;
$(function () {
    if((navigator && navigator.onLine) || (!navigator && window.navigator.onLine)) {
        $('#lblStatus').text('Online');
    } else {
        $('#lblStatus').text('Offline');
    }
    ViewModel = new Geo.CoordinateConverter.CoordinateConverterViewModel(new Geo.CoordinateConverter.Providers.DecimalAndDmsConverter(), document.getElementById('txtCoordinates'), document.getElementById('lblGps'), document.getElementById('lblDms'), document.getElementById('lblDecimalDegrees'), function () {
        return ViewModel.InputChanged();
    });
    ViewModel.GetPosition();
});
var map;
function initialize() {
    var mapCanvas = document.getElementById('map-canvas');
    var mapContainer = document.getElementById('map-container');
    if(((navigator && navigator.onLine) || (!navigator && window.navigator.onLine)) && google) {
        var coordinateDecimal = ViewModel.Model.ToCoordinateDecimal();
        if(zooming) {
            map.setCenter(new google.maps.LatLng(coordinateDecimal.Latitude, coordinateDecimal.Longitude));
            return;
        }
        var mapOptions = {
            zoom: 1,
            center: new google.maps.LatLng(coordinateDecimal.Latitude, coordinateDecimal.Longitude),
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        map = new google.maps.Map(mapCanvas, mapOptions);
        mapContainer.style.display = 'inline-block';
        zoomIn(mapOptions.zoom);
    }
}
var zooming = false;
function zoomIn(num) {
    var latLong = ViewModel.Model.ToCoordinateDecimal();
    var to = setTimeout(function () {
        var newZoom = num + 1;
        map.setCenter(new google.maps.LatLng(latLong.Latitude, latLong.Longitude));
        map.setZoom(newZoom);
        if(newZoom < 21) {
            zooming = true;
            zoomIn(newZoom);
        } else {
            zooming = false;
            map.setMapTypeId(google.maps.MapTypeId.HYBRID);
        }
    }, 1000);
}
